package base

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

var (
	err error
	//输出文件的目录名称
	fileOutPutDir string

	//文件名，类似controller/UserController
	fileNameWithPath string
)

//接口是一类方法（封装、抽象），实现类可以有多种实现（多态）
type IBase interface {
	GenerateFile(file string, fType string) error
}

//定义生成文件的相关参数
type Base struct {
	//生成的文件名
	Name string
	//简单的正则替换规则
	Format map[string]string
	//自动生成文件的路径
	OutPutDir string
}

//file 生成的文件名 userController.go
//fType  Controller,Model,Service, etc...
func (b Base) GenerateFile(fileContents string, fType string) error {
	//默认生成的目录名称
	fileOutPutDirDefault := "AutoGenOutPut"
	//批量替换模版内变量
	for key, val := range b.Format {
		fileContents = strings.ReplaceAll(fileContents, key, val)
	}
	//目录不为空为，则指定的OutPutDir目录
	fmt.Println("OutPutDir is", b.OutPutDir)

	if b.OutPutDir != "" {
		fileOutPutDir = filepath.Join(b.OutPutDir, fType)
	} else {
		//如果默认的文件夹存在
		//if _, err = os.Stat(fileOutPutDirDefault); err == nil {
		//	fileOutPutDir = filepath.Join(fileOutPutDirDefault, fType)
		//} else {
		//	//为空默认设置一个目录，
		fileOutPutDir = filepath.Join(fileOutPutDirDefault, fType)
		//}
	}
	fileName := b.Name + fType + ".go"
	fmt.Println("fileOutPutDir is", fileOutPutDir)
	fmt.Println("fileName is", fileName)
	if err = WriteFile(fileOutPutDir, fileName, fileContents, 0755); err != nil {
		return err
	}
	return nil
}

//写文件到指定位置
func WriteFile(fileOutPutDir string, fileName string, file string, mode os.FileMode) error {
	_, err = os.Stat(fileOutPutDir)
	if err != nil {
		err = os.MkdirAll(fileOutPutDir, mode)
		if err != nil {
			log.Fatalln("创建目录失败:", err.Error()+": "+fileOutPutDir)
		}
	}

	fileNameWithPath = filepath.Join(fileOutPutDir, fileName)
	if err = ioutil.WriteFile(fileNameWithPath, []byte(file), mode); err != nil {
		log.Fatalln("文件写入失败", err.Error()+": "+fileNameWithPath)
		return err
	}
	fmt.Println("自动创建成功，文件为 : " + fileNameWithPath)
	fmt.Println("=====================")
	return nil
}
